/*
 * Copyright (c) 2025 Huawei Device Co., Ltd.
 * Licensed under the Apache License, Version 2.0 (the 'License');
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

/**
 * All imports should come from `qvog-dsl`, and shouldn't depend on any
 * modules coming from the adapter or engine.
 */

import { BinaryExpression, is, rule } from '../../../src';

/**
 * This is an example DSL with all features demonstrated.
 *
 * Types that are `any` in DSL are native types of the engine and is opaque to the end user.
 * Therefore, users have to refer to the engine's documentation for detailed type definition.
 *
 * `skipped` property here has no practical meaning. It is only a demonstration of how
 * to define scoped custom properties to persist state across callbacks.
 *
 * Why `export default`? Because we can easier access the rule by import this file
 * as a module, and get it via `default`.
 * I cannot think of any better/simpler way to achieve this.
 */
export default // start of a DSL rule
// can define scoped custom properties to persist state across callbacks
rule({ skipped: 0 })
    // preliminary check, can also use callback with context as shown below
    .match(BinaryExpression) // .match((node, context) => BinaryExpression.is(node))
    // detailed check, context can be destructured
    .when((node, { config, props }) => {
        // nested utility function example
        function shouldSkip(pos: number) {
            // global configuration access
            return config.ignoreLines?.includes(pos);
        }

        // core logics
        if (is(node.right, BinaryExpression)) {
            if (shouldSkip(node.pos)) {
                props.skipped++;
                return false; // not matched (skipped)
            }
            return true; // matched
        }

        return false; // not matched
    })
    // issue report, will be invoked only if action in `when` returns `true`
    .report((node, { api, props, native }) => {
        // access engine-specific properties
        api.report({
            line: api.getLocation(node).range.start.line,
            message: `[${native.version}] BE with right as BE found, total skipped: ${props.skipped}`,
        });
    });
